package com.linkrenhe.frame.http;

import java.io.RandomAccessFile;

import android.util.Base64;



public class HttpUploadUtil {
	/**
	 * TAG
	 */
	private static final String TAG = "HttpUploadUtil";
	public static int BLOCK_SIZE = 4 * 1024 * 1024;	 // 4M
	public static int PUT_CHUNK_SIZE = 20 * 1024;	 // 256K
	public static String UP_HOST = "http://up.qbox.me";
	
	public static String UP_HOST_URL = "http://up.qbox.me/upload";
	public static final String REQEUST_HEADER_AUTHORIZTION = "Authorization";
	
	public static boolean isBlockEnd(long hasUploadBytes,long fileLength,int blockCount,int blockIndex){
		if((blockIndex+1) == blockCount){
			return (fileLength == hasUploadBytes);
		}else{
			return (hasUploadBytes % HttpUploadUtil.BLOCK_SIZE == 0);
		}
	}
	public static byte[] nextChunk(RandomAccessFile fileIO,long hasUploadBytes,
			long fileLength,int blockIndex,int blockCount) throws Exception{
		
		long blockRemain = getBlockRemain(hasUploadBytes, fileLength, blockIndex, blockCount);
		
		if(blockRemain>0){
			fileIO.seek(hasUploadBytes);
			
			int curChunkbyteLength =  (int) (blockRemain > HttpUploadUtil.PUT_CHUNK_SIZE ? 
					 HttpUploadUtil.PUT_CHUNK_SIZE : blockRemain);
			byte[] bytes = new byte[curChunkbyteLength];
			
			int readByteLength = fileIO.read(bytes, 0, curChunkbyteLength);
			if(readByteLength == curChunkbyteLength){
				return bytes;
			}
			throw new Exception("nextChunk     hasReadBytes:"+hasUploadBytes+"  fileLength:"+fileLength+"  blockIndex:"+blockIndex+"  blockCount:"+blockCount);
		}
		
		return null;
	}
	private static long getBlockRemain(long hasUploadBytes,
			long fileLength,int blockIndex,int blockCount){
		if((blockIndex+1) == blockCount){
			return fileLength - hasUploadBytes;
		}else{
			return (HttpUploadUtil.BLOCK_SIZE * (blockIndex+1)) - hasUploadBytes;
		}
	}
	public static long getBlockOffset(long hasUploadBytes,
			long fileLength,int blockIndex,int blockCount){
		if((blockIndex+1) == blockCount){
			return (fileLength - blockIndex * HttpUploadUtil.BLOCK_SIZE) - getBlockRemain(hasUploadBytes, fileLength, blockIndex, blockCount);
		}else{
			return HttpUploadUtil.BLOCK_SIZE - getBlockRemain(hasUploadBytes, fileLength, blockIndex, blockCount);
		}
		
	}
	public static int getBlockCount(long fileLength) {
		int blockCount = (int) (fileLength / HttpUploadUtil.BLOCK_SIZE);
		
		if(fileLength % HttpUploadUtil.BLOCK_SIZE >0){
			blockCount++;
		}
		
		return blockCount;
	}
	public static long makeBlockLength(long hasUploadBytes,
			long fileLength,int blockIndex,int blockCount){
		if((blockIndex+1) == blockCount){
			return fileLength - hasUploadBytes;
		}else{
			return HttpUploadUtil.BLOCK_SIZE;
		}
	}
	
	public static byte[] getCheckSums(String[] checkSumArrary){
		byte[] body = new byte[20 * checkSumArrary.length];
		
		for (int i = 0; i < checkSumArrary.length; i++) {
			
			byte[] buf = urlsafeDecode(checkSumArrary[i]) ;
			
			System.arraycopy(buf,  0, body, i * 20, buf.length);
		}
		return body;
	}
	
	/**
	 * 杞爜
	 * @param src
	 * @return
	 */
	public static String urlsafeEncodeString(byte[] src) {
		return new String(urlsafeEncodeBytes(src));
	}
	/**
	 * 杞爜
	 * @param text
	 * @return
	 */
	public static String urlsafeEncode(String text) {
		return new String(urlsafeEncodeBytes(text.getBytes()));
	}
	/**
	 * 杞爜
	 * @param src
	 * @return
	 */
	public static byte[] urlsafeEncodeBytes(byte[] src) {
		if (src.length % 3 == 0) {
			return Base64.encode(src, Base64.URL_SAFE | Base64.NO_WRAP);
		}
		
		byte[] b = Base64.encode(src, Base64.URL_SAFE | Base64.NO_WRAP);
		if (b.length % 4 == 0) {
			return b;
		}
		
		int pad = 4 - b.length % 4;
		byte[] b2 = new byte[b.length + pad];
		System.arraycopy(b, 0, b2, 0, b.length);
		b2[b.length] = '=';
		if (pad > 1) {
			b2[b.length+1] = '=';
		}
		return b2;
	}
	public static byte[] urlsafeDecode(String text) {
		byte[] buf = Base64.decode(text, Base64.URL_SAFE | Base64.NO_WRAP);
		return buf ;
	}
	
	
}
